#!/usr/bin/python
'''
convertGraph.py: 
	Take an input graph file and convert it to a suitable format for the
	partitioning/cluster programs (Community in this case).

	

Created on Apr 15, 2011
@author: cmhill
'''

import getopt
import networkx as nx
import sys

EDGE = "EDGE"
ADJ_LIST = "ADJ_LIST"

METIS = "METIS"
COMMUNITY = "COMMUNITY"

def createGraph(f, format):
	''' Creates and returns a networkx graph object from the input file. '''
	
	graph = nx.MultiDiGraph()

	for line in f.readlines():
		try:
			if (line.strip().startswith('#')):
				continue
			nodes = line.strip().split()
			
			if format is EDGE:
				# If edge input format:
				nodes = line.strip().split()
				graph.add_edge(nodes[0], nodes[1])
			else:
				# If adj list format:
				for neighbor in nodes[1:]:
					graph.add_edge(nodes[0], neighbor)
		except:
			print line

	return graph

def convertGraph(graph, outputFormat, output, output2):
	''' Convert the networkx graph to the desired output format. '''

	# need convert to numbered vertices starting at 0 with no gaps
	if outputFormat == COMMUNITY:
		nodemap = dict()
		count = 0
		for v in graph.nodes():
			nodemap[v] = str(count)
			count = count + 1
		for u, v in graph.edges():
			output.write( nodemap[u] + " " + nodemap[v] + "\n")

		# need a reverse map
		for v in nodemap.keys():
			output2.write( nodemap[v] + " " + str(v) + "\n")

def main():
	if ( len(sys.argv) != 4 ): 
		print ("usage:\n" +
			"\tconvertGraph_community.py input edge_list_output map_output \n" +
			"\t\tall parameters are file names\n")
		sys.exit()		
	
	outputGraphFormat = COMMUNITY
	inputGraphFormat = EDGE
	inputfile = file(sys.argv[1], 'r')
	outputfile = file(sys.argv[2], 'w')
	mapoutputfile = file(sys.argv[3], 'w')
	
	# Create the networkx representation of the graph.
	graph = createGraph(inputfile, inputGraphFormat)
	inputfile.close()	

	# Convert the graph to the desired format.
	convertGraph(graph, outputGraphFormat, outputfile, mapoutputfile)
	outputfile.close()
	mapoutputfile.close()	

if __name__ == '__main__':
	main()
